package models;

import play.*;
import play.data.validation.Unique;
import play.db.jpa.*;
//import play.modules.elasticsearch.annotations.ElasticSearchable;
import play.modules.elasticsearch.annotations.ElasticSearchable;
import play.mvc.results.RenderText;

import javax.persistence.*;

import java.util.*;

import com.mysql.jdbc.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.persistence.Entity;

import play.db.jpa.Model;
//import play.modules.elasticsearch.annotations.ElasticSearchable;
import javax.persistence.Entity;

@ElasticSearchable
/**
 * this annotation calls Elasticsearch module to enable the module to search for tutorials
 * @author Renad
 * */
@Entity
public class Tutorial extends Model {
	@Unique
	public String Title;
	
	private String summary;
	@ManyToOne
	@JoinColumn(name = "Ttopic")
	public Topic topicT;
	
	@Lob
	public String content;
	public String ExpLevel;
	@ManyToOne
	@JoinColumn(name = "Creator")
	public RegisteredUser creator;
	public String status;
	public String tutorialTags;

	@OneToMany
	public List<Comment> comments;
	@OneToMany
	public List<Media> media;
	@OneToMany
	public List<Comment> pcomments;

	@OneToMany(mappedBy = "tutEdits", cascade = CascadeType.ALL)
	public List<editVersion> edits;
	@ManyToMany(mappedBy = "contributedTutorials", cascade = CascadeType.ALL)
	public List<RegisteredUser> contributorsList;

	public int likeCount;

	@ManyToMany(mappedBy = "likeList", cascade = CascadeType.ALL)
	public List<RegisteredUser> likersList;
	@ManyToMany(mappedBy = "recommendList", cascade = CascadeType.ALL)
	public List<CommunityList> recommendedTutorials;

	@ManyToMany(mappedBy = "followedTuts", cascade = CascadeType.ALL)
	public List<RegisteredUser> tutsFollowers;
	@ManyToMany(mappedBy = "favoriteTuts", cascade = CascadeType.ALL)
	public List<RegisteredUser> FavoriteTutUsers;

	@OneToMany(mappedBy = "myTut", cascade = CascadeType.ALL)
	public List<Exercise> availableExercise;

	public int averageRate;
	public int rates;

	@ManyToMany(mappedBy = "rateList", cascade = CascadeType.ALL)
	public List<RegisteredUser> ratersList;

	public boolean ready; 

	/**
	 * The constructor of the Tutorial class. Creates new Tutorials.
	 * 
	 * @author Rana Amr
	 * @param title
	 *            , t, content, words, Exp, creator
	 */
	public Tutorial(String title, Topic topic, String content,String summary, String words,
			String Exp, RegisteredUser creator) {
		this.Title = title;
		this.topicT = topic;
		this.content = content;
		this.summary = summary;
		this.status = "draft"; // default of the tutorial is "draft" mode -->
								// Nourhan
		ExpLevel = Exp;
		this.creator = creator;
		// availableExercise = new List<Exercise>();
		// relatedKeywords= words;
		tutorialTags = words;
		likeCount = 0;
		this.recommendedTutorials = new ArrayList<CommunityList>();
		this.edits = new ArrayList();
		tutsFollowers = new ArrayList<RegisteredUser>();
		FavoriteTutUsers = new ArrayList<RegisteredUser>();
		this.contributorsList = new ArrayList<RegisteredUser>();
	}

	/***
	 * this method is for setting the status of the tutorial into publish
	 * 
	 * @author Nourhan Elmalahy
	 */
	public void publishTutorial() {
		status = "publish";
	}

	/***
	 * this method is for setting the status of the tutorial into hide
	 * 
	 * @author Nourhan Elmalahy
	 */
	public void hideTutorial() {
		status = "hide";
	}

	/**
	 * this method to get the raw title without the tags
	 * 
	 * @return rawTitle
	 * @author Omnia
	 */
	public String getRawTitle() {
		String t = this.Title;
		int size = t.length();
		String rawTitle = "";
		for (int i = 0; i < size; i++) {
			if (t.charAt(i) == '<') {
				while (t.charAt(i) != '>') {
					i++;
				}
			} else
				rawTitle += t.charAt(i);
		}

		return rawTitle;
	}

	public String getTitle() {
		return Title;
	}

	public void setTitle(String title) {
		Title = title;
		this.save();
	}

	public String getExpLevel() {
		return ExpLevel;
	}
	public String getSummary() {
		return summary;
	}

	public void setSummary(String summary) {
		this.summary = summary;
	}


	public void setExpLevel(String expLevel) {
		ExpLevel = expLevel;
		this.save();
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
		// this.save();
	}

	public String getStringofwords() {
		return tutorialTags;
	}

	public void setStringofwords(String stringofwords) {
		this.tutorialTags = stringofwords;
		this.save();
	}

	/**
	 * method to increment the likeCount in the DB
	 * 
	 * @author Omnia
	 */
	public void updateLikeCount() {
		this.likeCount++;
		this.save();
	}

	// Begin ----> Ebaa
	/**
	 * getter for contributorsList attribute
	 * 
	 * @author Ebaa
	 * @return List<RegisteredUser>
	 * 
	 */
	public List<RegisteredUser> getContributorsList() {
		return contributorsList;
	}

	/**
	 * setter for contributorsList attribute
	 * 
	 * @author Ebaa
	 * @param contributorsList
	 *            list of contributers of a tutorial
	 */
	public void setContributorsList(List<RegisteredUser> contributorsList) {
		this.contributorsList = contributorsList;
	}

	// End ----> Ebaa
	/**
	 * This method takes the uID and tID and return a true if the tutorial is
	 * not in the list of followed tutorial, and false if not
	 * 
	 * @param uID
	 *            which is the id of the current user.
	 * @param tID
	 *            which is the id of the tutorial I'm standing on.
	 * @return boolean true or false
	 * 
	 * @author Marwa
	 */
	public boolean followTutorial(long uID, long tID) {
		Tutorial tu = Tutorial.findById(tID);
		RegisteredUser user = RegisteredUser.findById(uID);
		if (user.followedTuts.contains(tu) == false) {
			user.followedTuts.add(tu);
			tu.tutsFollowers.add(user);
			tu.save();
			user.save();
			return true;
		} else {
			return false;
		}
	}

	public List<Exercise> getAvailableExercise() {
		return availableExercise;
	}

	public void setAvailableExercise(List<Exercise> availableExercise) {
		this.availableExercise = availableExercise;
	}

	/**
	 * This method takes the uID and tID and return a true if the tutorial is
	 * not in the list of favorites, and false if not
	 * 
	 * @param uID
	 *            which is the id of the current user.
	 * @param tID
	 *            which is the id of the tutorial I'm standing on.
	 * @return boolean true or false
	 * 
	 * @author Marwa
	 */
	public boolean addTutorialToFavorites(long uID, long tID) {
		Tutorial tu = Tutorial.findById(tID);
		RegisteredUser user = RegisteredUser.findById(uID);
		if (user.favoriteTuts.contains(tu) == false) {
			user.favoriteTuts.add(tu);
			tu.FavoriteTutUsers.add(user);
			tu.save();
			user.save();
			return true;
		} else {
			return false;
		}
	}

	/**
	 * This method check whether the tutorial is ready to publish or not.
	 * 
	 * @author Dina
	 * */
	public boolean isReady() {
		return ready;
	}

	/**
	 * This method set the tutorial ready to be published.
	 * 
	 * @author Dina
	 * */
	public void setReady(boolean ready) {
		this.ready = ready;
	}

}